#include <assert.h>

#include "kristyime.h"

BOOL InitIMEStructure(LPCOMPOSITIONSTRING lpCompStr, LPCANDIDATEINFO lpCandInfo) 
{
    LPKRISTYCOMPOSITIONSTRING lpKristyCompStr = NULL;
    LPKRISTYCANDIDATEINFO lpKristyCandInfo = NULL;
    LPCANDIDATELIST       lpCandList = NULL;

    assert(lpCompStr && lpCandInfo);

    // initialize composition string
    lpKristyCompStr = (LPKRISTYCOMPOSITIONSTRING)lpCompStr;
    memset(lpKristyCompStr, 0, sizeof(KRISTYCOMPOSITIONSTRING));
    lpKristyCompStr->cs.dwSize = sizeof(KRISTYCOMPOSITIONSTRING);

    // initialize candidate
    lpKristyCandInfo = (LPKRISTYCANDIDATEINFO)lpCandInfo;
    memset(lpKristyCandInfo, 0, sizeof(KRISTYCANDIDATEINFO));
    lpKristyCandInfo->ci.dwSize = sizeof(KRISTYCANDIDATEINFO);
    lpKristyCandInfo->ci.dwCount = 1;
    lpKristyCandInfo->ci.dwOffset[0] = 
        (DWORD)((LPBYTE)&lpKristyCandInfo->cl - (LPBYTE)lpKristyCandInfo);

    lpCandList = (LPCANDIDATELIST)(LPBYTE)lpCandInfo + lpKristyCandInfo->cl.dwOffset[0];
    for(size_t i = 0; i < MAXCANDSIZE; ++i) {
        lpKristyCandInfo->dwOffset[i] = (DWORD)((LPBYTE)&lpKristyCandInfo->szCandStr[i] - (LPBYTE)lpKristyCandInfo);
    }

    lpKristyCandInfo->kc.dwCountPerPage = 5;

    return TRUE;
}

BOOL SetCompStr(LPCOMPOSITIONSTRING lpCompStr, LPCANDIDATEINFO lpCandInfo)
{
    BOOL bRet = FALSE;

    LPKRISTYCOMPOSITIONSTRING lpKristyCompStr  = NULL;
    LPKRISTYCANDIDATEINFO     lpKristyCandInfo = NULL;
    LPCANDIDATELIST           lpCandList       = NULL;
    TCHAR* pszCompStr                      = NULL;

    size_t  nCountStart = 0;

    const ime_pinyin::uint16 *spelling_start;
    char buf[200] = {0};

    assert(lpCompStr || lpCandInfo );

    pszCompStr = GETLPCOMPSTR(lpCompStr);
    snprintf(buf, __min(sizeof(buf), _tcslen(pszCompStr)), "%S", pszCompStr);

    lpKristyCandInfo = (LPKRISTYCANDIDATEINFO)lpCandInfo;

    lpKristyCandInfo->kc.dwCurrentPage = 0;
    lpKristyCandInfo->kc.dwTotalCount  = ime_pinyin::im_search(buf, strlen(buf));

    for ( size_t i = 0; i < min(lpKristyCandInfo->kc.dwTotalCount, MAXCANDSIZE); ++i ) {
        ime_pinyin::im_get_candidate(i, (ime_pinyin::char16*)lpKristyCandInfo->szCandStr[i], MAXCOMPSIZE);
    }

    lpKristyCompStr = (LPKRISTYCOMPOSITIONSTRING)lpCompStr;
    memset(lpKristyCompStr->szCompStr, 0, sizeof(lpKristyCompStr->szCompStr));
    nCountStart = ime_pinyin::im_get_spl_start_pos(spelling_start);
    for(size_t i=0; i < nCountStart; ++i ) {
        _tcsncpy_s(&lpKristyCompStr->szCompStr[_tcslen(lpKristyCompStr->szCompStr)],
            MAXCOMPSIZE - _tcslen(lpKristyCompStr->szCompStr),
            &pszCompStr[spelling_start[i]],
            spelling_start[i+1] - spelling_start[i]);

        if(i != nCountStart - 1) {
            _tcscpy_s(&lpKristyCompStr->szCompStr[_tcslen(lpKristyCompStr->szCompStr)],
                MAXCOMPSIZE - _tcslen(lpKristyCompStr->szCompStr),
                TEXT("\'"));
        } 
    }

    bRet = TRUE;
Exit0:
    return bRet;
}

BOOL ClearCompStr(LPCOMPOSITIONSTRING lpCompStr, LPCANDIDATEINFO lpCandInfo)
{
    DWORD dwSize = 0;
    assert(lpCompStr || lpCandInfo);

    dwSize = lpCompStr->dwSize;
    memset(lpCompStr,  0, sizeof(*lpCompStr));
    lpCompStr->dwSize = dwSize;

    dwSize = lpCandInfo->dwSize;
    memset(lpCandInfo, 0, sizeof(*lpCandInfo));
    lpCandInfo->dwSize = dwSize;

    return (TRUE);
}